# Create your models here.
from django.db import models
from django.db.models import JSONField

class DeviceType(models.Model):
    name = models.CharField(max_length=50, unique=True)
    capabilities = JSONField()

class Device(models.Model):
    name = models.CharField(max_length=50, db_index=True)
    type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
    family = models.ForeignKey('user.Family', on_delete=models.CASCADE)
    meta = JSONField(null=True, blank=True)

    @classmethod
    def validate_state(cls, capabilities: dict, new_state: dict):
        """
        capabilities:  标准的 state 对象
        new_state:     客户端提交的 state 对象
        """
        for field, val in new_state.items():
            if field not in capabilities:
                return False, f"Field '{field}' not supported by this device type"

            spec = capabilities[field]
            # 只读字段
            if spec == "readonly":
                return False, f"Field '{field}' is read-only"

            # 布尔能力
            if spec is True:
                if not isinstance(val, bool):
                    return False, f"Field '{field}' must be boolean"

            # 枚举能力
            elif isinstance(spec, list):
                if val not in spec:
                    return False, f"Field '{field}' must be one of {spec}"

            # 范围能力
            elif isinstance(spec, dict):
                mn, mx = spec.get("min"), spec.get("max")
                if not (isinstance(val, (int, float)) and mn <= val <= mx):
                    return False, f"Field '{field}' must be number in [{mn}, {mx}]"

            else:
                return False, f"Unknown capability spec for '{field}'"

        return True, None

    def apply_state(self, new_state: dict, source: str):
        """
        1) 校验 new_state
        2) 写历史
        3) 合并/更新当前状态
        """
        ok, err = self.validate_state(self.type.capabilities, new_state)
        if not ok:
            raise ValueError(err)

        # 记录历史
        DeviceStateHistory.objects.create(
            device=self,
            state_json=new_state,
            command_source=source
        )

        # 合并并保存当前状态
        state_obj, created = DeviceState.objects.get_or_create(
            device=self,
            defaults={'state_json': new_state}
        )
        if not created:
            merged = state_obj.state_json.copy()
            merged.update(new_state)
            state_obj.state_json = merged
            state_obj.save()

class DeviceState(models.Model):
    device = models.OneToOneField(Device, primary_key=True, on_delete=models.CASCADE, related_name='state')
    state_json = JSONField()
    updated_at = models.DateTimeField(auto_now=True)

class DeviceStateHistory(models.Model):
    class Source(models.TextChoices):
        MANUAL = 'manual', '手动'
        SCENE = 'scene', '场景'

    device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='history')
    state_json = JSONField()
    ts = models.DateTimeField(auto_now_add=True)
    command_source = models.CharField(
        max_length=10,
        choices=Source.choices,
        default=Source.MANUAL,
        verbose_name="update_resource"
    )

